home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 by Christopher A. Wichura.
- See file GIFMachine.doc for full description of rights.
- */
-
- #include "GIFMachine.h"
- #include <iff/ILBM.h>
- #include <libraries/iffparse.h>
- #include <graphics/displayinfo.h>
- #include <graphics/view.h>
- #include <dos/datetime.h>
-
- #include <clib/iffparse_protos.h>
- extern struct Library *IFFParseBase;
- #include <pragmas/iffparse_lib.h>
-
- extern struct GIFdescriptor gdesc;
- EXTERNBITPLANE;
-
- extern struct MinList CommentList;
-
- extern char *AbortMsg;
-
- extern UWORD *SHAMmem;
- BYTE *PlaneBuf;
-
- extern BOOL DisplayCounts;
-
- BOOL Laced;
-
- UBYTE *Planes[24];
-
- static UBYTE CompBuf[256];
- static ULONG PlanePos;
-
- /* our version number stuff */
- extern ULONG __far Version;
- extern ULONG __far Revision;
-
- BOOL WriteIFF(char *tofile, BOOL DeepFlag)
- {
- register struct IFFHandle *iff;
- register int index;
- register ULONG ChunkSize;
- register UWORD current;
- struct DisplayInfo DspInfo;
- char WrittenBy[40];
-
- ColorRegister ColourBuf;
- BitMapHeader bmh;
-
- PutStr("...Writing IFF file.");
-
- if (!GetDisplayInfoData(NULL, (UBYTE *)&DspInfo, sizeof(struct
- DisplayInfo), DTAG_DISP, (Laced ? HAMLACE_KEY : HAM_KEY))) {
- PutStr("\n......Error trying to obtain display info.\n");
- return TRUE;
- }
-
- if (!(iff = AllocIFF())) {
- PutStr("\n......Error allocating IFF handle.\n");
- return TRUE;
- }
-
- if (!(iff->iff_Stream = Open(tofile, MODE_NEWFILE))) {
- MyPrintf("\n......Error %ld trying to create %s.", IoErr(), tofile);
- goto EndWriteIFF;
- }
-
- InitIFFasDOS(iff);
-
- if (OpenIFF(iff, IFFF_WRITE)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PushChunk(iff, ID_ILBM, ID_FORM, IFFSIZE_UNKNOWN)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PushChunk(iff, 0L, MAKE_ID('A','N','N','O'), IFFSIZE_UNKNOWN)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- MySPrintf(WrittenBy, "Written by GIFMachine v%ld.%ld on ", Version, Revision);
-
- if (WriteChunkBytes(iff, (APTR)&WrittenBy, strlen(WrittenBy)) != strlen(WrittenBy)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- {
- struct DateTime dat;
- char Date[LEN_DATSTRING + 1];
- int DateLength;
-
- DateStamp(&dat.dat_Stamp);
- dat.dat_Format = FORMAT_DOS;
- dat.dat_Flags = 0;
- dat.dat_StrDay = NULL;
- dat.dat_StrDate = Date;
- dat.dat_StrTime = NULL;
-
- memset(Date, 0, LEN_DATSTRING + 1);
- DateToStr(&dat);
-
- DateLength = strlen(Date) + 1;
- if (WriteChunkBytes(iff, (APTR)&Date, DateLength) != DateLength) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- {
- struct CommentNode *cn;
- char ANNObuf[1];
-
- #define C_BLOCK_ID "GIF Comment Block: "
-
- ANNObuf[0] = 0;
-
- while (cn = (struct CommentNode *)RemHead((struct List *)&CommentList)) {
- if (PushChunk(iff, 0L, MAKE_ID('A','N','N','O'), IFFSIZE_UNKNOWN)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (WriteChunkBytes(iff, (APTR)C_BLOCK_ID, strlen(C_BLOCK_ID)) != strlen(C_BLOCK_ID)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (WriteChunkBytes(iff, (APTR)cn->cn_Comment, cn->cn_CommentLength) != cn->cn_CommentLength) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (WriteChunkBytes(iff, (APTR)ANNObuf, 1) != 1) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
- }
-
- if (PushChunk(iff, 0L, ID_BMHD, sizeof(BitMapHeader))) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- bmh.w = (gdesc.gd_Width & 1) ? gdesc.gd_Width + 1 : gdesc.gd_Width;
- bmh.h = (gdesc.gd_Height & 1) ? gdesc.gd_Height + 1 : gdesc.gd_Height;
- bmh.x = bmh.y = 0;
- bmh.nPlanes = (DeepFlag ? 24 : 6);
- bmh.masking = mskNone;
- bmh.compression = cmpByteRun1;
- bmh.pad1 = 0;
- bmh.transparentColor = 0;
- bmh.xAspect = DspInfo.Resolution.x;
- bmh.yAspect = DspInfo.Resolution.y;
- bmh.pageWidth = 320;
- bmh.pageHeight = (Laced ? 400 : 200);
-
- if (WriteChunkBytes(iff, (APTR)&bmh, sizeof(BitMapHeader)) != sizeof(BitMapHeader)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PushChunk(iff, 0L, ID_CAMG, 4)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- {
- LONG CAMGbuf[1];
-
- CAMGbuf[0] = (DeepFlag ? 0 : HAM) | (Laced ? LACE : 0);
-
- if (WriteChunkBytes(iff, (APTR)&CAMGbuf, 4) != 4) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (!DeepFlag) {
- if (PushChunk(iff, 0L, ID_CMAP, 16 * 3)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- for (index = 0; index < 16; index++) {
- current = SHAMmem[index];
-
- ColourBuf.red = (current >> 4) & 0xF0;
- ColourBuf.green = current & 0xF0;
- ColourBuf.blue = (current & 15) << 4;
-
- if (WriteChunkBytes(iff, (APTR)&ColourBuf, sizeofColorRegister) != sizeofColorRegister) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- ChunkSize = (Laced ? gdesc.gd_Height / 2 : gdesc.gd_Height) * 16 * sizeof(UWORD);
-
- if (PushChunk(iff, 0L, MAKE_ID('S','H','A','M'), IFFSIZE_UNKNOWN)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- {
- UWORD SHAMversion[1];
-
- SHAMversion[0] = 0;
-
- if (WriteChunkBytes(iff, (APTR)&SHAMversion, sizeof(UWORD)) != sizeof(UWORD)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
-
- if (WriteChunkBytes(iff, (APTR)SHAMmem, ChunkSize) != ChunkSize) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (gdesc.gd_Height & 1) {
- UWORD BlankSHAM[16];
-
- memset((char *)BlankSHAM, 0, sizeof(BlankSHAM));
-
- if (WriteChunkBytes(iff, (APTR)BlankSHAM, sizeof(BlankSHAM)) != sizeof(BlankSHAM)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
- } /* end if (!DeepFlag) */
-
- if (PushChunk(iff, 0L, ID_BODY, IFFSIZE_UNKNOWN)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- /* now we actually write the body chunk out */
- {
- register int plane;
- register int col;
- register UWORD x;
- register UWORD y;
- register int index;
- UBYTE PlaneMask, ColMask;
- UWORD Cols;
-
- if (DisplayCounts)
- PutStr("\n......Line ");
- else
- PutStr("\n......Working");
- Flush(Output());
-
- Cols = (bmh.w + 7) / 8;
- if (IS_ODD(Cols))
- Cols++;
-
- for (y = 0; y < ((gdesc.gd_Height & 1) ? gdesc.gd_Height + 1 : gdesc.gd_Height) ; y++) {
- if (DisplayCounts)
- MyPrintf("%5ld", y);
-
- if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
- MyPrintf("\n%s", AbortMsg);
- CloseIFF(iff);
- Close(iff->iff_Stream);
- FreeIFF(iff);
- MyExit(ABORTEXITVAL);
- }
-
- if (y != gdesc.gd_Height)
- for (index = 0; index < (DeepFlag ? 3 : 1); index++) {
- col = 0;
- ColMask = 1L << 7;
-
- for (x = 0; x < gdesc.gd_Width; x++) {
- if (DeepFlag)
- current = *((UBYTE *)&BitPlane[y][x]+index);
- else
- current = GetValue(x, y);
-
- PlaneMask = 1;
- for (plane = 0; plane < (DeepFlag ? 8 : 6); plane++) {
- if (current & PlaneMask)
- Planes[plane + index * 8][col] |= ColMask;
-
- PlaneMask <<= 1;
- }
-
- if (ColMask == 1) {
- ColMask = 1L << 7;
- col++;
- } else
- ColMask >>= 1;
- }
- }
-
- /* now we need to compress the scan line */
-
- {
- register BOOL state;
- register char c;
- register char lastc;
- register UWORD nbuf;
- register UWORD rstart;
-
- for (plane = 0; plane < (DeepFlag ? 24 : 6); plane++) {
-
- CompBuf[0] = lastc = c = Planes[plane][0];
-
- state = FALSE;
- PlanePos = rstart = 0;
- nbuf = col = 1;
-
- while (col < Cols) {
- CompBuf[nbuf++] = c = Planes[plane][col++];
-
- switch (state) {
- case FALSE:
- if (nbuf > 128) {
- OutDump(nbuf - 1);
- CompBuf[0] = c;
- nbuf = 1;
- rstart = 0;
- break;
- }
-
- if (c == lastc) {
- if (nbuf - rstart >= 3) {
- if (rstart > 0)
- OutDump(rstart);
- state = TRUE;
- } else if (rstart == 0)
- state = TRUE;
- } else
- rstart = nbuf - 1;
-
- break;
-
- case TRUE:
- if ((c != lastc) || (nbuf - rstart > 128)) {
- OutRun(nbuf - 1 - rstart, lastc);
- CompBuf[0] = c;
- nbuf = 1;
- rstart = 0;
- state = FALSE;
- }
-
- break;
- }
-
- lastc = c;
- }
-
- switch (state) {
- case FALSE:
- OutDump(nbuf);
- break;
-
- case TRUE:
- OutRun(nbuf - rstart, lastc);
- break;
- }
-
- /* now write the compressed plane out */
- if (WriteChunkBytes(iff, (APTR)PlaneBuf, PlanePos) != PlanePos) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- memset((char *)Planes[plane], 0, Cols);
- }
- }
-
- if (DisplayCounts)
- MyPrintf("\x1B[5D");
- }
-
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- if (PopChunk(iff)) {
- PutStr("\n......Error writing to IFF.\n");
- goto EndWriteIFF;
- }
-
- MyPrintf("\x1B[%ldD\x1B[KWritten.\n", (DisplayCounts ? 5 : 7));
-
- EndWriteIFF:
- CloseIFF(iff);
- if (iff->iff_Stream)
- Close(iff->iff_Stream);
- FreeIFF(iff);
-
- return TRUE;
- }
-
- void OutDump(int nn)
- {
- register int index;
-
- PlaneBuf[PlanePos++] = nn - 1;
-
- for (index = 0; index < nn; index++)
- PlaneBuf[PlanePos++] = CompBuf[index];
- }
-
- void OutRun(int nn, int cc)
- {
- PlaneBuf[PlanePos++] = -(nn - 1);
- PlaneBuf[PlanePos++] = cc;
- }
-